package ar.com.aterrizar.entidades;

import java.util.ArrayList;
import java.util.Collection;


import com.lanchita.AerolineaLanchita;
import com.oceanic.AerolineaOceanic;
import ar.com.aterrizar.aerolineas.AeroLanchita;
import ar.com.aterrizar.aerolineas.AeroOceanic;
import ar.com.aterrizar.aerolineas.Aerolinea;
import ar.com.aterrizar.asientos.Asiento;
import ar.com.aterrizar.exception.ErrorClienteNoSTANDAR;
import ar.com.aterrizar.exception.VueloYaReservadoException;
import ar.com.aterrizar.operaciones.SobreReserva;

public class Aeropuerto {

	private static Aeropuerto INSTANCE;
	private static Aeropuerto INSTANCEMOCK;
	private SobreReserva sobreReserva;
	private Collection<Asiento> listaDeAsientosConFormato;
	private Collection<Asiento> asientosConFormato;
	private Collection<Aerolinea> aerolineas = new ArrayList<Aerolinea>();
	private AeroLanchita aeroLanchita;
	private AeroOceanic aeroOceanic;

	public static Aeropuerto getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new Aeropuerto();
			INSTANCE.sobreReserva=new SobreReserva();
		}
		return INSTANCE;
	}

	protected Aeropuerto() {
		aeroLanchita = AeroLanchita.getInstance();
		aeroOceanic = AeroOceanic.getInstance();
		aerolineas.add(aeroLanchita);
		aerolineas.add(aeroOceanic);
	}

	/**
	 * Solo para test
	 * 
	 * @param lanchitaMock
	 * @param oceanicMock
	 * @return
	 */
	public static Aeropuerto getInstanceMock(AerolineaLanchita lanchitaMock, AerolineaOceanic oceanicMock) {
		if (INSTANCEMOCK == null) {
			INSTANCEMOCK = new Aeropuerto(lanchitaMock, oceanicMock);
		}
		return INSTANCEMOCK;
	}

	/**
	 * Solo para test
	 * 
	 * @param lanchitaMock
	 * @param oceanicMock
	 */
	protected Aeropuerto(AerolineaLanchita lanchitaMock, AerolineaOceanic oceanicMock) {
		aerolineas.add(new AeroLanchita(lanchitaMock));
		aerolineas.add(new AeroOceanic(oceanicMock));
	}

	public Collection<Asiento> getAsientos(String origen, String fechaSalida) {
		listaDeAsientosConFormato = new ArrayList<Asiento>();
		asientosConFormato = new ArrayList<Asiento>();
		for (Aerolinea aerolinea : aerolineas) {
			asientosConFormato = aerolinea.getAsiento(origen, fechaSalida);
			if (!(asientosConFormato == null)) 
				listaDeAsientosConFormato.addAll(asientosConFormato);	
			}
			return listaDeAsientosConFormato;
	}

	public Collection<Asiento> getAsientos(String origen, String fechaSalida,
			String destino) {

		listaDeAsientosConFormato = new ArrayList<Asiento>();
		asientosConFormato = new ArrayList<Asiento>();
		for (Aerolinea aerolinea : aerolineas) {
			asientosConFormato = (aerolinea.getAsiento(origen, fechaSalida, destino));
			if (!(asientosConFormato == null)) 
				listaDeAsientosConFormato.addAll(asientosConFormato);	
			}
			return listaDeAsientosConFormato;
	}

	public Collection<Asiento> getAsiento(String origen, String fechaSalida,
			String horaSalida, String destino, String fechaLlegada,
			String horaLlegada) {

		listaDeAsientosConFormato = new ArrayList<Asiento>();
		asientosConFormato = new ArrayList<Asiento>();

		for (Aerolinea aerolinea : aerolineas) {
			asientosConFormato = (aerolinea.getAsiento(origen, fechaSalida,	horaSalida, destino, fechaLlegada, horaLlegada));
			if (!(asientosConFormato == null)){
				listaDeAsientosConFormato.addAll(asientosConFormato);
			}
		}
		return listaDeAsientosConFormato;
	}

	public void comprar(Asiento asiento, Cliente cliente) {
		if (asiento.estaReservado(cliente)||!asiento.estaReservado()) {
			this.realizarCompra(asiento, cliente);
		} else {
			throw new VueloYaReservadoException();
		}

	}

	public void realizarCompra(Asiento asiento, Cliente cliente) {
		asiento.getAerolinea().comprar(asiento, cliente);
		asiento.getAerolinea().vuelosComprados().add(asiento);
		sobreReserva.eliminarSobreReserva(asiento);
	}

	public void reservar(Asiento asiento, Cliente cliente) {
		
//		TODO:La lineas de abajo estan comentadas para que ser pueda ver la sobreReserva unicamente
//		if(asiento.estaReservado(cliente)){
//			throw new UserException("El asiento ya se encuentra reservado"); 
//		}
		
		if(asiento.estaReservado()){
			throw new VueloYaReservadoException();
		}
		if (cliente.getIdCategoria() != Categoria.STANDARD) {
			throw new ErrorClienteNoSTANDAR();	
		}
		asiento.getAerolinea().reservar(asiento, cliente);
		asiento.getReserva().agregarClienteAReservas(cliente);
	}
	public void SobreReservar(Cliente cliente, Asiento asiento){
		sobreReserva.addAsiento(asiento);
		sobreReserva.addReserva(cliente, asiento);
	}
	public SobreReserva getSobreReserva(){
		return sobreReserva;
	}
	public boolean estaSobreReservado(Asiento asiento,Cliente cliente){
		for(Asiento asientoTmp:this.sobreReserva.getAsiento()){
			if(asiento.getCodigoDeAsiento().equals(asientoTmp.getCodigoDeAsiento())){
				for(Cliente clienteTmp:asientoTmp.getReserva().getClientes()){
					if(cliente.getDni().equals(clienteTmp.getDni())){
						return true;
					}
				}
				return false;
			}
		}
		return false;
	}
}
